package com.pactera.madp.cp.job;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.pactera.madp.admin.api.vo.SysFileVo;
import com.pactera.madp.common.core.util.SpringContextHolder;
import com.pactera.madp.cp.api.em.workmessage.MsgTypeEnum;
import com.pactera.madp.cp.api.entity.wm.WorkMsgEntity;
import com.pactera.madp.cp.api.entity.wm.WorkMsgIndexEntity;
import com.pactera.madp.cp.api.entity.wm.WorkMsgTableMgtEntity;
import com.pactera.madp.cp.api.model.wm.ChatRsaKeyModel;
import com.pactera.madp.cp.api.model.wm.CorpMsgTO;
import com.pactera.madp.cp.api.model.wm.DataResultModel;
import com.pactera.madp.cp.common.config.FileUploadConfig;
import com.pactera.madp.cp.common.constant.Const;
import com.pactera.madp.cp.common.util.CommandUtil;
import com.pactera.madp.cp.common.util.DateUtils;
import com.pactera.madp.cp.common.util.RSAUtils;
import com.pactera.madp.cp.common.util.file.FilesUtil;
import com.pactera.madp.cp.common.util.wm.WorkMsgHelper;
import com.pactera.madp.cp.config.MsgStoreConfig;
import com.pactera.madp.cp.config.WxProxyConfig;
import com.pactera.madp.cp.mapper.wm.WorkMsgIndexMapper;
import com.pactera.madp.cp.mapper.wm.WorkMsgMapper;
import com.pactera.madp.cp.service.IWorkMsgService;
import com.pactera.madp.cp.service.IWorkMsgTableMgtService;
import com.tencent.wework.Finance;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.DigestUtils;
import org.springframework.util.StringUtils;

import java.io.File;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author: yangpengwei
 * @time: 2020/11/13 3:38 下午
 * @description 企业微信会话内存存档工具类
 */
@Slf4j
@Component
public class WorkMsgBackUpUtil {

    private static final Logger LOGGER = LoggerFactory.getLogger(WorkMsgBackUpUtil.class);
    private static final String MSG_ACTION_SWITCH = "switch";
    private static long sdk = 1;

    private static WorkMsgMapper workMsgMapper;
    private static WorkMsgIndexMapper workMsgIndexMapper;
    private static IWorkMsgTableMgtService workMsgTableMgtService;
    private static MsgStoreConfig msgStoreConfig;
    private static FileUploadConfig config;

    @Autowired
    public void setWorkMsgMapper(WorkMsgMapper workMsgMapper) {
        WorkMsgBackUpUtil.workMsgMapper = workMsgMapper;
    }
    @Autowired
    public void setWorkMsgIndexMapper(WorkMsgIndexMapper workMsgIndexMapper) {
        WorkMsgBackUpUtil.workMsgIndexMapper = workMsgIndexMapper;
    }
    @Autowired
    public void setWorkMsgTableMgtService(IWorkMsgTableMgtService workMsgTableMgtService) {
        WorkMsgBackUpUtil.workMsgTableMgtService = workMsgTableMgtService;
    }
    @Autowired
    public void setMsgStoreConfig(MsgStoreConfig msgStoreConfig) {
        WorkMsgBackUpUtil.msgStoreConfig = msgStoreConfig;
    }
    @Autowired
    public void setFileUploadConfig(FileUploadConfig config) {
        WorkMsgBackUpUtil.config = config;
    }

    public static void setSdk() {
        sdk = 0;
    }

    private static void initSDK(CorpMsgTO entity) {
        if (sdk == 0) {
            sdk = Finance.NewSdk();
            int result = Finance.Init(sdk, entity.getWxCorpId(), entity.getChatSecret());
            if (result == 0) {
                LOGGER.debug("init SDK 成功 >>>>> " + entity.toString());
            } else {
                LOGGER.debug("init SDK 失败 >>>>> <<<<< " + entity.toString());
            }
        }
    }

    /**
     * 从企业微信拉取数据保存到数据库, 一次拉取 100 条
     *
     * @param entity 企业会话内容存档配置信息
     * @param seq    最后一条数据的 seq
     * @return 是否拉取完成所有数据
     */
    public static boolean insertMsg(CorpMsgTO entity, long seq) {
        // 是否需要代理
        String proxy = WxProxyConfig.isEnabled() ? StrUtil.format("http://{}:{}", WxProxyConfig.getIp(), WxProxyConfig.getPort()) : "";

        List<WorkMsgEntity> msgEntities = new ArrayList<>();
        ArrayList<WorkMsgIndexEntity> msgIndexEntities = new ArrayList<>();
        Map<String, WorkMsgIndexEntity> msgIndexEntityMap = new ConcurrentHashMap<>();
        initSDK(entity);
        long slice = Finance.NewSlice();
        long ret = Finance.GetChatData(sdk, seq, msgStoreConfig.getLimit(), proxy, "", msgStoreConfig.getTimeout(), slice);
        if (ret != 0) {
            LOGGER.debug("拉取数据失败，错误码：" + ret);
        } else {
            LOGGER.debug("拉取数据成功 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
            String contentJson = Finance.GetContentFromSlice(slice);
            Finance.FreeSlice(slice);
            LOGGER.debug(contentJson);
            LOGGER.debug("拉取数据成功 <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<");

            // 解析原始数据
            DataResultModel dataResultModel = JSON.parseObject(contentJson, DataResultModel.class);
            int code = dataResultModel.getErrcode();
            if (0 == code) {
                List<DataResultModel.ChatdataDTO> chatdataDTOList = dataResultModel.getChatdata();
                if (null != chatdataDTOList && chatdataDTOList.size() > 0) {
                    // 获取私钥
                    String keyJson = entity.getChatRsaKey();

                    ChatRsaKeyModel rsaKeyModel = JSON.parseObject(keyJson, ChatRsaKeyModel.class);
                    String privateKey = rsaKeyModel.getPrivateKey();
                    int version = rsaKeyModel.getVersion();

                    int corpId = entity.getCorpId();
                    WorkMsgEntity workMsgEntity;
                    WorkMsgIndexEntity workMsgIndexEntity;
                    for (int i = 0; i < chatdataDTOList.size(); i++) {
                        DataResultModel.ChatdataDTO chatdataDTO = chatdataDTOList.get(i);
                        if (chatdataDTO.getPublickey_ver() != version) {
                            continue;
                        }
                        String decryptDataJson = decryptData(chatdataDTO, privateKey);

                        JSONObject jsonObject = JSON.parseObject(decryptDataJson);
                        String action = getStringValue(jsonObject, "action");
                        if (action.isEmpty() || MSG_ACTION_SWITCH.equals(action)) {
                            continue;
                        }
                        String msgType = getStringValue(jsonObject, "msgtype", "text");
                        if (msgType.toUpperCase().equals("DISAGREE")){
                            continue;
                        }
                        workMsgEntity = transChatModelToWorkMsg(jsonObject, corpId, chatdataDTO.getSeq());
                        msgEntities.add(workMsgEntity);

                        // 正向
//                        workMsgIndexEntity = transWorkMsgToIndex(workMsgEntity);
//                        msgIndexEntities.add(workMsgIndexEntity);
//                        if (!msgIndexEntityMap.containsKey(workMsgIndexEntity.getFlag())) {
//                            msgIndexEntityMap.put(workMsgIndexEntity.getFlag(), workMsgIndexEntity);
//                        }

                        // 反向
//                        reverseWorkMsgIndex(workMsgIndexEntity);
//                        msgIndexEntities.add(workMsgIndexEntity);
//                        if (!msgIndexEntityMap.containsKey(workMsgIndexEntity.getFlag())) {
//                            msgIndexEntityMap.put(workMsgIndexEntity.getFlag(), workMsgIndexEntity);
//                        }
                    }
                } else {
                    return false;
                }
            } else {
                LOGGER.error("会话内容存档数据拉取失败 >>>>>>>>>>>>>>>>>>>>>>>>>>>");
                LOGGER.error(dataResultModel.getErrmsg());
                LOGGER.error("会话内容存档数据拉取失败 >>>>>>>>>>>>>>>>>>>>>>>>>>>");
            }
            LOGGER.debug("会话内容存档数据存储 >>>>>>>>>>>>>>>>>>>>>>>>>>>");
            LOGGER.debug("" + msgEntities.size());
            LOGGER.debug(msgEntities.toString());
            LOGGER.debug("会话内容存档数据存储 >>>>>>>>>>>>>>>>>>>>>>>>>>>");

            if (msgEntities.size() > 0) {
                boolean flag = workMsgMapper.insertByMap(workMsgTableMgtService.getEnableSubTable(), msgEntities);
                // 记录最后消息序列号
                if (flag) {
                    WorkMsgTableMgtEntity we = new WorkMsgTableMgtEntity();
                    we.setLastSeq(SpringContextHolder.getBean(IWorkMsgService.class).findLastSeq(false));
                    workMsgTableMgtService.update(we, Wrappers.<WorkMsgTableMgtEntity>lambdaUpdate()
                            .eq(WorkMsgTableMgtEntity::getState, 1));
                }
            }
//            if (msgIndexEntityMap.size() > 0) {
//                Set<String> flags = msgIndexEntityMap.keySet();
//                QueryWrapper<WorkMsgIndexEntity> queryWrapper = new QueryWrapper<WorkMsgIndexEntity>();
//                queryWrapper.select("flag");
//                queryWrapper.in("flag", flags);
//                List<WorkMsgIndexEntity> existFlags = workMsgIndexMapper.selectList(queryWrapper);
//
//                for (WorkMsgIndexEntity existIndex : existFlags) {
//                    if (msgIndexEntityMap.containsKey(existIndex.getFlag())) {
//                        msgIndexEntityMap.remove(existIndex.getFlag());
//                    }
//                }
//
//                List<WorkMsgIndexEntity> list = new ArrayList<>(msgIndexEntityMap.values());
//                workMsgIndexMapper.insertMsgIndex(list);
//            }
        }
        return msgEntities.size() == msgStoreConfig.getLimit();
    }

    /**
     * 数据解密
     *
     * @param chatdataDTO 未解密数据
     * @param privateKey  私钥
     * @return 解密后字符串
     */
    private static String decryptData(DataResultModel.ChatdataDTO chatdataDTO, String privateKey) {
        String encryptRandomKey = chatdataDTO.getEncrypt_random_key();
        String encryptChatMsg = chatdataDTO.getEncrypt_chat_msg();
        String decryptRandomKey = RSAUtils.decryptByPriKey(encryptRandomKey, privateKey);

        long slice = Finance.NewSlice();
        long ret = Finance.DecryptData(sdk, decryptRandomKey, encryptChatMsg, slice);
        if (ret != 0) {
            LOGGER.debug("会话内容存档数据拉取失败 >>>>>>>>>>>>>>>>>>>>>>>>>>>");
            LOGGER.debug("数据解密错误码：" + ret);
            LOGGER.debug("会话内容存档数据拉取失败 >>>>>>>>>>>>>>>>>>>>>>>>>>>");
        }
        String decryptChatMsg = Finance.GetContentFromSlice(slice);
        LOGGER.warn("数据解密内容 :" + decryptChatMsg);
        Finance.FreeSlice(slice);

        return decryptChatMsg;
    }

    /**
     * 对获取 jsonObject 进行转换以便于数据库存储
     *
     * @param jsonObject jsonObject 数据对象
     * @param corpId     企业 id
     * @param seq        seq
     */
    private static WorkMsgEntity transChatModelToWorkMsg(JSONObject jsonObject, int corpId, long seq) {
        //获取消息类型
        String msgType = getStringValue(jsonObject, "msgtype", "text");
        int msgTypeCode = MsgTypeEnum.valueOf(msgType.toUpperCase()).getCode();

        //获取消息动作 0-send(发送消息) 1-recall(撤回消息) 2-switch(切换企业日志)
        String actionStr = getStringValue(jsonObject, "action");
        int action;
        if ("switch".equals(actionStr)) {
            action = 2;
        } else if ("recall".equals(actionStr)) {
            action = 1;
        } else {
            action = 0;
        }

        String content;
        JSONObject tempJsonObj;
        //
        if ("external_redpacket".equals(msgType)) {
            content = getStringValue(jsonObject, "redpacket");
        }
        else if ("voip_doc_share".equals(msgType)) {
            tempJsonObj = jsonObject.getJSONObject("voip_doc_share");
            tempJsonObj.put("voipid", getStringValue(jsonObject, "voipid"));
            content = tempJsonObj.toString();
        }
        else if ("meeting_voice_call".equals(msgType)) {
            tempJsonObj = jsonObject.getJSONObject("meeting_voice_call");
            tempJsonObj.put("voiceid", getStringValue(jsonObject, "voiceid"));
            content = tempJsonObj.toString();
        }
        else if ("news".equals(msgType) || "markdown".equals(msgType)) {
            content = getStringValue(jsonObject, "info");
        }
        //
        else if ("docmsg".equals(msgType)) {
            content = getStringValue(jsonObject, "doc");
        }
        //默认为文本text
        else {
            content = getStringValue(jsonObject, msgType);
        }

        content = onContentMachine(msgType, content);

        JSONArray toList = jsonObject.getJSONArray("tolist");
        int toListSize = 0;
        if (toList != null) {
            toListSize = toList.size();
        }
        int toType = 0;
        if (toListSize == 1) {
            String toWxUserId = toList.getString(0);
            if (isContact(toWxUserId)) {
                toType = 1;
            } else {
                // 内部联系人
                toType = 0;
            }
        } else {
            // 群聊
            toType = 2;
            if(toList == null) {
                //群里就群主一人,所以发给自己
                List<String> toList_ = new ArrayList<>();
                toList_.add(getStringValue(jsonObject,"from"));
                jsonObject.put("tolist",JSONObject.toJSONString(toList_));
            }
        }

        WorkMsgEntity workMsgEntity = new WorkMsgEntity();
        workMsgEntity.setCorpId(corpId);
        workMsgEntity.setSeq(seq);
        workMsgEntity.setMsgId(getStringValue(jsonObject, "msgid"));
        workMsgEntity.setAction(action);
        workMsgEntity.setFrom(getStringValue(jsonObject, "from"));
        workMsgEntity.setTolist(getStringValue(jsonObject, "tolist"));
        workMsgEntity.setTolistType(toType);
        workMsgEntity.setMsgType(msgTypeCode);
        workMsgEntity.setContent(content);
        workMsgEntity.setMsgTime(getStringValue(jsonObject, "msgtime"));
        workMsgEntity.setWxRoomId(getStringValue(jsonObject, "roomid"));

        LOGGER.debug("workMsg", workMsgEntity.toString());
        return workMsgEntity;
    }

    /**
     * 根据 WorkMsgEntity 创建 WorkMsgIndexEntity 索引对象
     *
     * @param workMsgEntity
     * @return WorkMsgIndexEntity 索引对象
     */
    private static WorkMsgIndexEntity transWorkMsgToIndex(WorkMsgEntity workMsgEntity) {
//        int corpId = workMsgEntity.getCorpId();
        int corpId = 1;
        int toType = workMsgEntity.getTolistType();

        //获取发送人id
        int fromId;
        String fromWxUserId = workMsgEntity.getFrom();
        Integer fId;
        if (isContact(fromWxUserId)) {
            fId = workMsgIndexMapper.selectContactId(corpId, fromWxUserId);
        } else {
            fId = workMsgIndexMapper.selectEmployeeId(corpId, fromWxUserId);
        }
        fromId = null == fId ? 0 : fId;

        //获取接收人id
        int toId = 0;
        JSONArray toList = JSON.parseArray(workMsgEntity.getTolist());
        int toListSize = toList.size();
        if (toListSize == 1) {
            String toWxUserId = toList.getString(0);
            Integer tId;
            if (isContact(toWxUserId)) {
                // 外部联系人
                tId = workMsgIndexMapper.selectContactId(corpId, toWxUserId);
            } else {
                // 内部联系人
                tId = workMsgIndexMapper.selectEmployeeId(corpId, toWxUserId);
            }
            toId = null == tId ? 0 : tId;
        } else if (toListSize > 1) {
            // 群聊
            String toWxUserId = toList.getString(0);
            Integer rId = workMsgIndexMapper.selectRoomId(corpId, toWxUserId);
            toId = null == rId ? 0 : rId;
        }

        WorkMsgIndexEntity indexEntity = new WorkMsgIndexEntity();
        indexEntity.setCorpId(corpId);
        indexEntity.setToId(toId);
        indexEntity.setToType(toType);
        indexEntity.setFromId(fromId);
        indexEntity.setFlag(fromId + "-" + toType + "-" + toId);
        return indexEntity;
    }

    /**
     * 根据 WorkMsgEntity 创建 WorkMsgIndexEntity 索引对象
     *
     * @param workMsgIndexEntity
     * @return WorkMsgIndexEntity 索引对象
     */
    private static WorkMsgIndexEntity reverseWorkMsgIndex(WorkMsgIndexEntity workMsgIndexEntity) {
        int fromId = workMsgIndexEntity.getToId();
        int toId = workMsgIndexEntity.getFromId();
        int toType = workMsgIndexEntity.getToType();
        workMsgIndexEntity.setFromId(fromId);
        workMsgIndexEntity.setToType(toType);
        workMsgIndexEntity.setFlag(fromId + "-" + toType + "-" + toId);
        return workMsgIndexEntity;
    }

    public static boolean isContact(String wxUserID) {
        if (StringUtils.hasLength(wxUserID) && wxUserID.length() > 2) {
            //判断是否是非机器人的外部联系人
            String flag = wxUserID.substring(0,2);
            return flag.contains("wo") || wxUserID.contains("wm");
        } else {
            return false;
        }
    }

    /**
     * 对内容里包含 item 的字符串进行适配处理
     *
     * @param msgType 消息类型
     * @param content 消息体
     * @return 适配后的消息体
     */
    private static String onContentMachine(String msgType, String content) {
        JSONObject jsonObject = JSON.parseObject(content);
        LOGGER.error(">>>>>><<<<<<: " + jsonObject);
        if ("emotion".equalsIgnoreCase(msgType)) {
            jsonObject.put("emotionType", jsonObject.getIntValue("type"));
            LOGGER.error(">>>>>><<<<<< emotion: " + jsonObject);
        }
        jsonObject.put("type", msgType);
        onSaveFileOfContent(msgType, jsonObject);
        if (jsonObject.containsKey("item")) {
            JSONArray jsonArray = jsonObject.getJSONArray("item");
            for (int i = 0; i < jsonArray.size(); i++) {
                JSONObject jsonObject1 = jsonArray.getJSONObject(i);
                msgType = jsonObject1.getString("type").replace("ChatRecord", "");
                Map<String, Object> map = jsonObject1.getJSONObject("content").getInnerMap();
                map.put("type", msgType);
                jsonObject1.remove("content");
                jsonObject1.fluentPutAll(map);
                onSaveFileOfContent(msgType, jsonObject1);
            }
        }
        return jsonObject.toJSONString();
    }

    /**
     * 保存文件并上传到阿里云
     *
     * @param msgType
     * @param jsonObject
     */
    private static void onSaveFileOfContent(String msgType, JSONObject jsonObject) {
        if (jsonObject.containsKey("sdkfileid")) {
            String sdkFileId = jsonObject.getString("sdkfileid");
            String fileSuffix;
            if ("image".equalsIgnoreCase(msgType)) {
                fileSuffix = ".jpg";
            } else if ("voice".equalsIgnoreCase(msgType)) {
                fileSuffix = ".amr";
            } else if ("video".equalsIgnoreCase(msgType)) {
                fileSuffix = ".mp4";
            } else if ("file".equalsIgnoreCase(msgType)) {
                fileSuffix = "." + jsonObject.getString("fileext");
            } else if ("emotion".equalsIgnoreCase(msgType)) {
                LOGGER.error("emotion: " + jsonObject.toJSONString());
                int type = jsonObject.getIntValue("emotionType");
                fileSuffix = 1 == type ? ".gif" : ".png";
            } else {
                fileSuffix = ".txt";
            }

            try {
                String filePathOss = onSaveFileAndUpload(sdkFileId, fileSuffix);
                jsonObject.put("ossPath", filePathOss);
            } catch (IOException e) {
                log.error(e.getMessage(), e);
            }
        }
    }

    /**
     * 保存文件并上传到阿里云
     *
     * @param sdkFileId
     * @param fileSuffix 文件类型
     */
    private static String onSaveFileAndUpload(String sdkFileId, String fileSuffix) throws IOException {
        // 拼接文件名
        String fileName = DateUtils.formatS7(System.currentTimeMillis())
                + "/"
                + new Random().nextInt(100)
                + "/"
                + DigestUtils.md5DigestAsHex(sdkFileId.getBytes())
                + fileSuffix;

        // 将文件保存至本地
        File file = new File(msgStoreConfig.getMsgTempFileDir(), fileName);
        if (!file.getParentFile().exists()) {
            file.getParentFile().mkdirs();
        }
        onWriteToFile(file, sdkFileId, "");

        // amr 格式音频转换
        if (".amr".equals(fileSuffix)) {
            String amrPath = file.getAbsolutePath();
            String mp3Path = amrPath.replace(fileSuffix, ".mp3");
            CommandUtil.amrToMp3(amrPath, mp3Path);
            File mp3File = new File(mp3Path);
            if (mp3File.exists()) {
                file = mp3File;
                fileName = msgStoreConfig.getMsgFileDir() + "/" + fileName.replace(fileSuffix, ".mp3");
            } else {
                LOGGER.error(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ");
                LOGGER.error(" amr 转 mp3 转换失败 " + file.getName());
                LOGGER.error(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ");
                return config.getAccessPath() + msgStoreConfig.getMsgFileDir() + "/" + fileName.replace(fileSuffix, ".mp3");
            }
        }

        // 文件上传至阿里云
        //AliyunOssUtils.upLoad(file, fileName);
        SysFileVo vo = FilesUtil.uploadFile(file, fileName);
        fileName = vo.getUrl();
        return fileName;
    }

    /**
     * 将微信文件保存到本地, 微信文件数据采取的是分片拉取
     *
     * @param file
     * @param sdkFileId
     * @param indexBuf  偏移量
     */
    private static void onWriteToFile(File file, String sdkFileId, String indexBuf) {
        long mediaData = Finance.NewMediaData();
        int ret = Finance.GetMediaData(sdk, indexBuf, sdkFileId, "", "", msgStoreConfig.getTimeout(), mediaData);
        if (ret != 0) {
            LOGGER.warn("获取媒体数据 " + ret);
        } else {
            LOGGER.debug("upload media " + sdkFileId);
            byte[] b = Finance.GetData(mediaData);
            boolean isFinish = Finance.IsMediaDataFinish(mediaData) > 0;
            String outIndex = Finance.GetOutIndexBuf(mediaData);
            try {
                //FileUtils.writeByteArrayToFile(file, b, true);
                FileUtil.writeBytes(b, file, 0, b.length, true);
            } catch (Exception e) {
                log.error("-----tempfile write failed-----" + sdkFileId,e);
            }
            Finance.FreeMediaData(mediaData);
            if (isFinish) {
                LOGGER.debug("upload media finish " + sdkFileId);
            } else {
                onWriteToFile(file, sdkFileId, outIndex);
            }
        }
    }

    private static String getStringValue(JSONObject jsonObject, String key) {
        return getStringValue(jsonObject, key, "");
    }

    private static String getStringValue(JSONObject jsonObject, String key, String defaultValue) {
        String value = jsonObject.getString(key);
        return null == value ? defaultValue : value;
    }

    // 测试用
    /*msgEntities = buildTestData(seq, msgStoreConfig.getLimit());
    public static List<WorkMsgEntity> buildTestData(long seq, int size) {
        if (seq >= msgStoreConfig.getMaxCount()) {
            size--;
        }

        List<WorkMsgEntity> list = new ArrayList<>(size);
        if (seq > 0) {
            seq++;
        }
        size += seq;
        String data = FileUtil.readLines(new File("C:\\Users\\pactera\\Desktop\\syncdata\\msg_test.txt"), CharsetUtil.CHARSET_UTF_8).get(0);
        WorkMsgEntity src = JSONUtil.toBean(data, WorkMsgEntity.class);

        // 会话人容器 from/tolist
        // from
        //String[] froms = new String[]{"LiXiang/97","LeiJun","ZhangDeMing/120","LiuJunLiang","HuangCong","YiQingChen/119","Fell","YuXiaoNan"};
        String[] froms = new String[]{"LiXiang","YiQingChen","ZhangDeMing"};

        // tolist
        //String[] tolists = new String[]{"LeiJun/16","LiuJunLiang/9","HuangCong/25","Fell/1","YuXiaoNan/4"};
        String[] tolists = new String[]{"[\"wmyp0APwAA7KgWUhlayaVcU8h6NaS8zw\"]","[\"wmyp0APwAAp-_bg6PvhHqKbJUUefjxCg\"]","[\"wmyp0APwAA2tOP_v7l4H_BkdY0R9qLVg\"]","[\"wmyp0APwAAQEnDV2tb6_uiprQPva-SRg\"]","[\"wmyp0APwAAjE7kOrxGnjCGbcxwx39peg\"]",};

        // 会话容器
        String[] contents = new String[]{
                "{\"type\": \"text\", \"content\": \"我有新的工作变更，雷俊@中电金信软件有限公司将接替我的工作，继续为您服务。\"}",
                "{\"type\": \"text\", \"content\": \"欢迎您，莫怀戚！\"}",
                "{\"type\": \"text\", \"content\": \"卧龙手工山药片，配料小麦粉，山药，棕榈油，辣椒，花椒，香辛料，食用盐呵呵呵呵呵\"}",
                "{\"type\": \"text\", \"content\": \"这个需要做分页吗\"}",
                "{\"type\": \"text\", \"content\": \"永恒哥\"}",
                "{\"type\": \"text\", \"content\": \"塔利班吧\"}",
                "{\"type\": \"text\", \"content\": \"那客户加了很多成员，这个列表不是很长吗\"}",
                "{\"type\": \"text\", \"content\": \"不用做分页。客户信息查询不也是一次性查回来的嘛\"}",
                "{\"type\": \"text\", \"content\": \"做分页也是个假的分页嘛\"}",
                "{\"type\": \"text\", \"content\": \"现在的客户管理里面有这个跳转吗？\"}",
                "{\"type\": \"text\", \"content\": \"没有\"}",
                "{\"type\": \"text\", \"content\": \"只做了展示\"}",
                "{\"type\": \"text\", \"content\": \"那就先不做。\"}",
                "{\"type\": \"text\", \"content\": \"好的\"}",
                "{\"type\": \"text\", \"content\": \"有\"}",
                "{\"type\": \"text\", \"content\": \"塔利班呢\"}",
                "{\"type\": \"text\", \"content\": \"入群引导了\"}",
                "{\"type\": \"text\", \"content\": \"交接\"}",
                "{\"type\": \"text\", \"content\": \"你好\"}",
                "{\"type\": \"text\", \"content\": \"你也好\"}",
                "{\"type\": \"text\", \"content\": \"测试\"}",
                "{\"type\": \"text\", \"content\": \"我来也\"}",
                "{\"type\": \"text\", \"content\": \"今天天气好\"}",
                "{\"type\": \"text\", \"content\": \"明天下雨吗\"}",
                "{\"type\": \"text\", \"content\": \"旅行去了\"}",
                "{\"type\": \"text\", \"content\": \"今晚吃什么好呢\"}",
                "{\"type\": \"text\", \"content\": \"不知道哦\"}",
                "{\"type\": \"text\", \"content\": \"塔利班吗\"}"
        };

        for (long i=seq; i<size; i++) {
            WorkMsgEntity dest = new WorkMsgEntity();
            BeanUtil.copyProperties(src, dest);
            dest.setMsgId(IdUtil.fastSimpleUUID() + "_external");
            dest.setSeq(i);
            dest.setMsgTime(String.valueOf(System.currentTimeMillis() - 1000000000));

            int r = randomInt(0, 100);

            String from = "";
            String tolist = "";
            if (r < 30 || r > 50) {
                int tIdx = randomInt(0, 3);
                tolist = "[\"" + froms[tIdx] + "\"]";
                int tolistIdx = randomInt(0, 5);
                from= tolists[tolistIdx];
                from = from.replace("[","").replace("]","").replace("\"","");
            } else {
                int tIdx = randomInt(0, 3);
                from = froms[tIdx];
                int tolistIdx = randomInt(0, 5);
                tolist= tolists[tolistIdx];
            }

            int cIdx = randomInt(0, 28);

            dest.setFrom(from);
            dest.setTolist(tolist);
            dest.setContent(contents[cIdx]);
            dest.setCorpId(10);
            list.add(dest);
        }
        return list;
    }*/

    private static int randomInt(int min, int max) {
        return RandomUtil.randomInt(min, max);
    }
}
